﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Windows.Controls.Primitives;
using System.Windows.Threading;
using mshtml;
using form= System.Windows.Forms;

namespace WpfWebBrowser
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        private bool IsLoadCompleted  =false;
        private const string DisableScriptError =
           @"function noError() {
                 return true;
              }
      window.onerror = noError;";
        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);

            foreach (var item in this.BrowserHost.Items)
            {
                var tabItem = item as TabItem;
                if (tabItem != null)
                {
                    var helperInstance = HelperRegistery.GetHelperInstance(tabItem);
                    if (helperInstance != null)
                    {
                        helperInstance.NewWindow -= WebBrowserOnNewWindow;
                        helperInstance.Disconnect();
                    }
                }
            }
        }

        private void CreateNewTab(Uri uri)
        {

            
            timer.Stop();

            var webBrowser = new WebBrowser { Source = uri };
           // SuppressScriptErrors(webBrowser, true);
            var helper = new ObjectForScriptingHelper(this);
            webBrowser.ObjectForScripting = helper;
            

            webBrowser.Navigated += WebBrowserOnNavigated;
            webBrowser.LoadCompleted+=webBrowser_LoadCompleted;
            webBrowser.Unloaded+=webBrowser_Unloaded;

            var tabItem = new TabItem { Content = webBrowser };

            tabItem.Height = 40;
            tabItem.MouseDoubleClick+=tabItem_MouseDoubleClick;
            var webBrowserHelper = new WebBrowserHelper(webBrowser);
            HelperRegistery.SetHelperInstance(tabItem, webBrowserHelper);
            webBrowserHelper.NewWindow += WebBrowserOnNewWindow;

            this.BrowserHost.Items.Add(tabItem);
            tabItem.IsSelected = true;
           
        }

        private void webBrowser_Unloaded(object sender, RoutedEventArgs e)
        {
           
        }

        private void webBrowser_LoadCompleted(object sender, NavigationEventArgs e)
        {
            var htmldoc = (sender as WebBrowser).Document as mshtml.HTMLDocument;
            //htmldoc.documentElement.style.overflow = "hidden";
            var head = htmldoc.getElementsByTagName("head").Cast<HTMLHeadElement>().First();
            var script = (IHTMLScriptElement)htmldoc.createElement("script");
            script.text = "function noError() {return true;}" +
                          "window.onerror = noError;" +
                          "function top(){document.documentElement.scrollTop-=400}" +
                          "function down(){document.documentElement.scrollTop+=400}" +
                          "function todown(){document.documentElement.scrollTop=document.documentElement.scrollHeight}" +
                          "function totop(){document.documentElement.scrollTop=0}";
            head.appendChild((IHTMLDOMNode)script);
            var title = htmldoc.getElementsByTagName("title").Cast<HTMLTitleElement>().First();

            var tabItem = BrowserHost.SelectedItem as TabItem;
            if (tabItem != null) tabItem.Header = title.text;
            timer.Start();
            this.IsLoadCompleted = true;


        }

        private void tabItem_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            var item = sender as TabItem;
            if (BrowserHost.Items.Count <= 1) return;
            if (item != null) BrowserHost.Items.Remove(item);
        }

        private void WebBrowserOnNavigated(object sender, NavigationEventArgs e)
        {
            dynamic browser = sender;
            //InjectDisableScript(browser);
            browser.Parent.Header = browser.Document.IHTMLDocument2_title;

            var htmldoc = browser.Document as mshtml.HTMLDocument;
            //htmldoc.documentElement.style.overflow = "hidden";
            var head = htmldoc.getElementsByTagName("head").Cast<HTMLHeadElement>().First();
            var script = (IHTMLScriptElement)htmldoc.createElement("script");
            script.text = "function noError() {return true;}" +
                          "window.onerror = noError;";
            head.appendChild((IHTMLDOMNode)script);
        }

        private void WebBrowserOnNewWindow(object sender, CancelEventArgs e)
        {
            this.IsLoadCompleted = false;
            dynamic browser = sender;
            dynamic activeElement = browser.Document.activeElement;
            // 这儿是在新窗口中打开，如果要在内部打开，改变当前browser的Source就行了
            try
            {
                var link = activeElement.ToString();

                var uri = new Uri(link);
                CreateNewTab(uri);
                e.Cancel = true;
            }
            catch (Exception)
            {
                e.Cancel = true;
                MessageBox.Show("地址无效!");
                throw;
            }
        }
        DispatcherTimer timer = new DispatcherTimer();

        private void Window_Loaded_1(object sender, RoutedEventArgs e)
        {
            var dizhi = ConfigurationManager.AppSettings["dizhi"];
            if (string.IsNullOrEmpty(dizhi))
            {
                MessageBox.Show("配置文件丢失或无效!");
                Environment.Exit(0);
            }
            CreateNewTab(new Uri(dizhi));
            timer.Interval = TimeSpan.FromMilliseconds(200);
            timer.Tick += timer_Tick;
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            var item = BrowserHost.SelectedItem as TabItem;
            if(item == null) return;

            var browser = item.Content as WebBrowser;
            if(browser.Document == null)
            BrowserHost.Items.Remove(item);

            if (BrowserHost.Items.Count == 0)
            {
                CreateNewTab(new Uri(ConfigurationManager.AppSettings["dizhi"]));
            }
        }

        void SuppressScriptErrors(WebBrowser webBrowser, bool hide)
        {
            webBrowser.Navigating += (s, e) =>
                {
                    var fiComWebBrowser = typeof(WebBrowser).GetField("_axIWebBrowser2", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
                    if (fiComWebBrowser == null)
                        return;

                    object objComWebBrowser = fiComWebBrowser.GetValue(webBrowser);
                    if (objComWebBrowser == null)
                        return;

                    objComWebBrowser.GetType().InvokeMember("Silent", System.Reflection.BindingFlags.SetProperty, null, objComWebBrowser, new object[] { hide });
                };
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            System.Threading.Thread.Sleep(2000);
       

            var browser = BrowserHost.SelectedContent as WebBrowser;
            
            try
            {
               
                browser.InvokeScript("top");
                
            }
            catch (Exception)
            {
                throw;
            }
        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            //System.Threading.Thread.Sleep(1500);
            WebBrowser browser = BrowserHost.SelectedContent as WebBrowser;


        
            var uira = browser.Source ;
           // MessageBox.Show(uira.OriginalString);
            System.Threading.Thread.Sleep(2000);
           // if(IsLoadCompleted)
            //{
             //   MessageBox.Show(uira.OriginalString);
            try
            {
                browser.InvokeScript("down");
            }
            catch (Exception)
            {
                throw;
            }
            
           // }
           
        }

        private void Button_Click_0(object sender, RoutedEventArgs e)
        {
            //System.Threading.Thread.Sleep(2000);
            var browser = BrowserHost.SelectedContent as WebBrowser;
            try
            {
                browser.InvokeScript("totop");
            }
            catch (Exception ex)
            {
               // MessageBox.Show(ex.Message);
            }
        }

        private void Button_Click_3(object sender, RoutedEventArgs e)
        {
            //System.Threading.Thread.Sleep(2000);
            var browser = BrowserHost.SelectedContent as WebBrowser;
            try
            {
                browser.InvokeScript("todown");

            }
            catch (Exception)
            {
                throw;
            }
        }

        private void Button_Click_4(object sender, RoutedEventArgs e)
        {
            //System.Threading.Thread.Sleep(2000);
            var browser = BrowserHost.SelectedContent as WebBrowser;
            if (browser != null) browser.Navigate(new Uri(ConfigurationManager.AppSettings["dizhi"]));
        }
        private void Button_Click_keyboard(object sender, RoutedEventArgs e)
        {
            var k = new keyboard(this);
            k.Show();
            var browser = BrowserHost.SelectedContent as WebBrowser;
            browser.Focus();
        }

        private void Key_OnClick(object sender, RoutedEventArgs e)
        {
            var browser = BrowserHost.SelectedContent as WebBrowser;
            browser.Focus();
             var keyEventArgs = new KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 1110, Key.A);
             keyEventArgs.RoutedEvent = UIElement.KeyDownEvent;
             RaiseEvent(keyEventArgs);

        }

        [ComImport, Guid("6D5140C1-7436-11CE-8034-00AA006009FA"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        private interface IOleServiceProvider
        {
            [PreserveSig]
            int QueryService([In] ref Guid guidService, [In] ref Guid riid, [MarshalAs(UnmanagedType.IDispatch)] out object ppvObject);
        }


        public static void SetSilent(WebBrowser browser, bool silent)
        {
            if (browser == null)
                throw new ArgumentNullException("browser");

            // get an IWebBrowser2 from the document
            IOleServiceProvider sp = browser.Document as IOleServiceProvider;
            if (sp != null)
            {
                Guid IID_IWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046");
                Guid IID_IWebBrowser2 = new Guid("D30C1661-CDAF-11d0-8A3E-00C04FC9E26E");

                object webBrowser;
                sp.QueryService(ref IID_IWebBrowserApp, ref IID_IWebBrowser2, out webBrowser);
                if (webBrowser != null)
                {
                    webBrowser.GetType().InvokeMember("Silent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.PutDispProperty, null, webBrowser, new object[] { silent });
                }
            }
        }

    }
}
